package com.zhang.single;

//懒汉式单例
//道高一尺，魔高一丈   通过源码分析

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;

//并发下面 加锁
public class LazyMan {
    private static boolean q = false;
    private LazyMan(){
        if(q==false){
            q=true;
        }else {
            throw new RuntimeException("不要试图使用反射破坏异常");
        }
//        if(lazyMan!=null){
//            throw new RuntimeException("不要试图使用反射破坏异常");
//        }
//        System.out.println(Thread.currentThread().getName()+"ok");
    }
    private volatile static LazyMan lazyMan;
    //双重检测锁模式的 懒汉式单例 DCL懒汉式
    public static LazyMan getInstance(){
        if(lazyMan==null){
            synchronized (LazyMan.class){
                if(lazyMan==null){
                    lazyMan = new LazyMan();//不是一个原子性操作
                    /*
                    1. 分配内存空间
                    2. 执行构造方法，初始化对象
                    3. 把真个对象指向这个空间

                    要保证不会指令重排
                     */
                }
            }
        }
        return lazyMan; //此时lazyMan还没有完成构造
    }

    //反射！ 去破坏单例
    public static void main(String[] args) throws Exception {
        // instance = LazyMan.getInstance();

        Field q = LazyMan.class.getDeclaredField("q");
        q.setAccessible(true);

        Constructor<LazyMan> declaredConstructor = LazyMan.class.getDeclaredConstructor(null);
        declaredConstructor.setAccessible(true);

        LazyMan instance =declaredConstructor.newInstance();

        q.set(instance,false);

        LazyMan instance2 =declaredConstructor.newInstance();

        System.out.println(instance2);
        System.out.println(instance);
    }
}


/*
    //多线程并发
    public static void main(String[] args){
        for(int i = 0;i<10; i++){
            new Thread(()->{
                LazyMan.getInstance();
            }).start();
        }
    }
 */